<template>
  <div class="cx-attach">
    <!-- 附件列表 -->
    <div v-if="attachList.length > 0" class="attach-list">
      <div 
        v-for="(attach, index) in attachList" 
        :key="attach.netId || index"
        class="attach-item"
      >
        <!-- 文件图标 -->
        <i :class="getFileIconClass(attach.title)" class="attach-icon"></i>
        
        <!-- 文件信息 -->
        <div v-if="attach.progress === undefined || attach.progress >= 1" class="attach-info">
          <div class="attach-name" :title="attach.title">{{ attach.title }}</div>
          <div class="attach-size">{{ formatFileSize(attach.size) }}</div>
        </div>
        
        <!-- 上传进度 -->
        <div v-else class="attach-progress">
          <el-progress 
            :percentage="Math.round((attach.progress || 0) * 100)"
            :status="attach.progress >= 1 ? 'success' : null"
          />
        </div>
        
        <!-- 操作按钮 -->
        <div v-if="attach.progress === undefined || attach.progress >= 1" class="attach-actions">
          <el-button 
            type="primary" 
            icon="el-icon-download" 
            size="small"
            @click="handleDownload(attach)"
          >
            下载
          </el-button>
          <el-button 
            v-if="editable"
            type="danger" 
            icon="el-icon-delete" 
            size="small"
            @click="handleDelete(attach)"
          >
            删除
          </el-button>
        </div>
      </div>
    </div>
    
    <!-- 上传区域 -->
    <div 
      v-if="editable"
      class="upload-area"
      @click="handleUpload"
    >
      <i class="el-icon-upload upload-icon"></i>
      <div class="upload-text">点击上传附件</div>
      <div class="upload-hint">支持各种文件格式</div>
    </div>
    
    <!-- 隐藏的文件输入 -->
    <input
      ref="fileInput"
      type="file"
      multiple
      style="display: none"
      @change="handleFileChange"
    />
  </div>
</template>

<script>
/**
 * 组件名称: Attach (Element UI 版本)
 * 功能说明: 附件上传和管理组件
 * 研发时间: 2025/11/17
 * 研发人员: AI Assistant
 */

export default {
  name: 'Attach',
  
  props: {
    editable: {
      type: Boolean,
      default: true
    },
    controller: {
      type: Object,
      required: true
    },
    busType: {
      type: String,
      default: '0'
    },
    showDownLoadBtn: {
      type: Boolean,
      default: false
    }
  },
  
  data() {
    return {
      attachList: [],
      uploadProgressListener: null
    }
  },
  
  computed: {
    currentAttachList() {
      if (this.controller && typeof this.controller.getAttachList === 'function') {
        return this.controller.getAttachList(this.busType)
      }
      return []
    }
  },
  
  created() {
    this.initComponent()
  },
  
  beforeUnmount() {
    if (this.controller && this.uploadProgressListener) {
      this.controller.removeUploadProgressListener(this.uploadProgressListener)
    }
  },
  
  methods: {
    initComponent() {
      this.updateAttachList()
      this.bindControllerEvents()
    },
    
    bindControllerEvents() {
      if (this.controller && typeof this.controller === 'object') {
        this.uploadProgressListener = (fileBean, progress) => {
          const attachIndex = this.attachList.findIndex(a => a.url === fileBean.url)
          if (attachIndex !== -1) {
            this.$set(this.attachList[attachIndex], 'progress', progress)
          }
        }
        
        if (typeof this.controller.addUploadProgressListener === 'function') {
          this.controller.addUploadProgressListener(this.uploadProgressListener)
        }
      }
    },
    
    updateAttachList() {
      const newAttachList = this.currentAttachList
      this.attachList = newAttachList.map(attach => {
        const newAttach = { ...attach }
        if (newAttach.progress === undefined) {
          this.$set(newAttach, 'progress', 1)
        }
        return newAttach
      })
    },
    
    handleUpload() {
      if (!this.editable) return
      this.$refs.fileInput.click()
    },
    
    async handleFileChange(event) {
      const files = Array.from(event.target.files)
      if (files.length === 0) return
      
      for (const file of files) {
        await this.uploadSingleFile(file)
      }
      
      // 清空input
      event.target.value = ''
    },
    
    async uploadSingleFile(file) {
      try {
        const title = typeof this.controller.getTitle === 'function'
          ? this.controller.getTitle({}, this.busType)
          : file.name
        
        const fileBean = {
          title: title || file.name,
          userRawTitle: !!title,
          url: URL.createObjectURL(file),
          file: file,
          busType: this.busType,
          mediaType: this.getMediaType(file.name),
          memo: this.controller.memo || '',
          task: this.controller.task || '',
          progress: 0,
          netId: 0,
          size: file.size
        }
        
        this.$set(fileBean, 'progress', 0)
        
        // 通过 controller 方法添加文件，避免直接修改 prop
        if (typeof this.controller.addFile === 'function') {
          this.controller.addFile(fileBean)
        } else {
          // 通过事件通知父组件
          this.$emit('file-add', fileBean)
        }
        
        this.updateAttachList()
        
        // 上传文件
        await this.controller.uploadFile(
          this.controller.entityId,
          fileBean,
          this.handleUploadSuccess,
          {}
        )
        
        this.$emit('upload-complete', fileBean)
      } catch (error) {
        this.$message.error('上传附件失败: ' + error.message)
        console.error('上传附件失败:', error)
      }
    },
    
    getMediaType(filename) {
      if (!filename) return 'UNKNOWN'
      
      const ext = filename.toLowerCase().split('.').pop()
      
      const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']
      const videoExts = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm']
      const docExts = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt']
      
      if (imageExts.includes(ext)) return 'PIC'
      if (videoExts.includes(ext)) return 'VIDEO'
      if (docExts.includes(ext)) return 'DOC'
      
      return 'UNKNOWN'
    },
    
    getFileIconClass(filename) {
      if (!filename) return 'el-icon-document'
      
      const ext = filename.toLowerCase().split('.').pop()
      
      switch (ext) {
        case 'pdf':
          return 'el-icon-document'
        case 'doc':
        case 'docx':
          return 'el-icon-document'
        case 'xls':
        case 'xlsx':
          return 'el-icon-document'
        case 'ppt':
        case 'pptx':
          return 'el-icon-document'
        case 'txt':
          return 'el-icon-document'
        case 'zip':
        case 'rar':
          return 'el-icon-folder-opened'
        case 'jpg':
        case 'jpeg':
        case 'png':
        case 'gif':
          return 'el-icon-picture'
        case 'mp4':
        case 'avi':
        case 'mov':
          return 'el-icon-video-camera'
        default:
          return 'el-icon-document'
      }
    },
    
    formatFileSize(bytes) {
      if (!bytes || bytes === 0) return '0 B'
      
      const k = 1024
      const sizes = ['B', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      
      return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
    },
    
    handleDownload(attach) {
      const link = document.createElement('a')
      link.href = attach.url
      link.download = attach.title
      link.click()
    },
    
    async handleDelete(attach) {
      try {
        await this.$confirm('确定要删除这个附件吗？', '确认删除', {
          type: 'warning'
        })
        
        if (this.controller && typeof this.controller.delFile === 'function') {
          await this.controller.delFile(attach, {})
          this.$emit('attach-deleted', attach)
          this.$message.success('删除成功')
        }
      } catch (error) {
        if (error !== 'cancel') {
          this.$message.error('删除失败: ' + error.message)
        }
      }
    },
    
    handleUploadSuccess(result) {
      console.log('附件上传成功:', result)
    }
  }
}
</script>

<style lang="scss" scoped>
.cx-attach {
  padding: 10px;
}

.attach-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.attach-item {
  display: flex;
  align-items: center;
  padding: 12px;
  background: #f8f9fa;
  border-radius: 5px;
  transition: all 0.3s;
  
  &:hover {
    background: #e9ecef;
  }
}

.attach-icon {
  font-size: 32px;
  margin-right: 12px;
  color: #6c757d;
}

.attach-info {
  flex: 1;
  min-width: 0;
}

.attach-name {
  font-size: 14px;
  color: #333;
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.attach-size {
  font-size: 12px;
  color: #999;
}

.attach-actions {
  display: flex;
  gap: 8px;
}

.attach-progress {
  flex: 1;
  margin-right: 12px;
}

.upload-area {
  border: 2px dashed #dee2e6;
  border-radius: 5px;
  padding: 40px;
  text-align: center;
  cursor: pointer;
  transition: all 0.3s;
  
  &:hover {
    border-color: #409eff;
    background: #ecf5ff;
  }
}

.upload-icon {
  font-size: 48px;
  color: #6c757d;
  margin-bottom: 10px;
}

.upload-text {
  font-size: 14px;
  color: #6c757d;
  margin-bottom: 5px;
}

.upload-hint {
  font-size: 12px;
  color: #999;
}
</style>
